#ifndef __WIZ_GEOMETRY_INTERSECTION_HPP__SHANHAOBO_19800429__
#define __WIZ_GEOMETRY_INTERSECTION_HPP__SHANHAOBO_19800429__

#include "./Bounding/WizGeometryAABB.hpp"
#include "./WizGeometryPlane.hpp"
#include "./WizGeometryRay.hpp"
#include "./WizGeometrySphere.hpp"

namespace Wiz
{
    template<class ElementT>
    struct WIZ_EXPORT Intersection
    {
        //////////////////////////////////////////////////////////////////////////
        typedef ElementT                                    tElement;
        typedef ::Wiz::Vector3::Type<tElement>        tVector3;
        typedef ::Wiz::Ray::Type<tElement>                  tRay;
        typedef ::Wiz::Plane::Type<tElement>                tPlane;
        typedef ::Wiz::Sphere::Type<tElement>         tSphere;
        typedef ::Wiz::AABB::Type<tElement>           tAABB;
        //////////////////////////////////////////////////////////////////////////

        //////////////////////////////////////////////////////////////////////////
        /// Ray ^ Plane
        ::Wiz::Bool::Type operator()(const tRay& InRay, const tPlane& InPlane);

        /// OutPnt : Intersection Point
        ::Wiz::Bool::Type operator()(tVector3& OutPnt, const tRay& InRay, const tPlane& InPlane);

        WIZ_INLINE ::Wiz::Bool::Type operator()(const tPlane& InPlane, const tRay& InRay)
        {
            return this->operator ()(InRay, InPlane);
        }

        WIZ_INLINE ::Wiz::Bool::Type operator()(tVector3& OutPnt, const tPlane& InPlane, const tRay& InRay)
        {
            return this->operator ()(OutPnt, InRay, InPlane);
        }

        //////////////////////////////////////////////////////////////////////////
        /// Ray ^ Sphere
        ::Wiz::Bool::Type operator()(const tRay& InRay, const tSphere& InSphere);

        //////////////////////////////////////////////////////////////////////////
        /// Ray ^ Sphere
        ::Wiz::Int::Type operator()(tVector3& OutPnt1, tVector3& OutPnt2, const tRay& InRay, const tSphere& InSphere);

        WIZ_INLINE ::Wiz::Bool::Type operator()(const tSphere& InSphere, const tRay& InRay)
        {
            return this->operator ()(InRay, InSphere);
        }

        WIZ_INLINE ::Wiz::Int::Type operator()(tVector3& OutPnt1, tVector3& OutPnt2, const tSphere& InSphere, const tRay& InRay)
        {
            return this->operator ()(OutPnt1, OutPnt2, InRay, InSphere);
        }

        //////////////////////////////////////////////////////////////////////////
        /// Ray ^ AABB
        ::Wiz::Bool::Type operator()(const tRay& InRay, const tAABB& InAABB);

        WIZ_INLINE ::Wiz::Bool::Type operator()(const tAABB& InAABB, const tRay& InRay)
        {
            return this->operator ()(InRay, InAABB);
        }
    }; /// end of namespace Intersection
} /// end of namespace Wiz

#endif /*__WIZ_GEOMETRY_INTERSECTION_HPP__SHANHAOBO_19800429__*/
